/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.pa165.pa165languageschoolclient;

import com.pa165.languageschoolpersistence.entities.Difficulty;
import com.pa165.languageschoolpersistence.entities.LanguageSpoken;
import com.pa165.languageschoolservice.DTO.CourseDTO;
import com.pa165.languageschoolservice.DTO.LectureDTO;
import com.sun.jersey.api.client.ClientHandlerException;
import java.io.IOException;
import java.net.Authenticator;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.InputMismatchException;
import java.util.List;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Elena Medvedeva
 */
public class CommandLineClient {
    
    public static final String HOST = "localhost";
    public static final int PORT = 8080;
    public static final String WEBAPP = "pa165";
    public static final String BASE = "webresources";
    public static final  String FORMAT = "yyyy-MM-dd";
    public static final String DEFAULT_USER="rest";
    public static final String DEFAULT_PASSWORD="rest";
    public static final String USER_PASSWORD="?j_username=" + DEFAULT_USER + "&j_password=" + DEFAULT_PASSWORD;
    
    public static String getURL(){
        return "http://" + HOST + ":" + PORT + "/" + WEBAPP + "/" + BASE + "/";
    }
    
    public static void showAllCourses(ClientCourse clientCourse){
         List<CourseDTO> output =  clientCourse.getAllCourses();        
               for(CourseDTO co:output){
                   System.out.println("course:" + co.toString());
               }
    }
    
    public static void greeting(){
         System.out.println("LanguageSchool Command Line Client, press 0 for Help, 1 for Exit");
    }
    
    public static void printHelp(){
         System.out.println("Help:");
         System.out.println("0 - Help");
         System.out.println("1 - Exit");
         System.out.println("11 - All Courses");
         System.out.println("12 - Get Course By Id");
         System.out.println("13 - Get Course By Name");
         System.out.println("14 - Add Course");
         System.out.println("15 - Modify Course");
         System.out.println("16 - Delete Course");
         System.out.println("21 - All Lectures");
         System.out.println("22 - Get Lecure By Id");
         System.out.println("23 - Get Lecure By Course");
         System.out.println("24 - Add Lecture");
         System.out.println("25 - Modify Lecture");
         System.out.println("26 - Delete Lecture");
    }
    
   public static void printAllCourses(ClientCourse clientCourse){
       System.out.println("All courses");
         List<CourseDTO> output =  clientCourse.getAllCourses();        
               for(CourseDTO co:output){
                   System.out.println( co.toString());
               }
    }
   
    public static void printCourse(ClientCourse clientCourse, final Scanner in) {
        System.out.println("Enter course id:");
        try {
           int id = in.nextInt();
            CourseDTO course = clientCourse.getCourse(id);
            if(course != null) {
                 System.out.println(course);
            }
        } catch (final InputMismatchException e) {
            System.out.println("Id should be a number. You have entered an invalid input. Try again.");
            in.next();    // discard non-int input
            
        }
    }
    
    public static void printCourseByName(ClientCourse clientCourse, final Scanner in) {
        System.out.println("Enter course name:");
        try {
            String name = in.next();          
            List<CourseDTO> courses = clientCourse.findByName(name);
            if (courses == null) {
                System.out.println("No courses found with name " + name);
            } else {
                for (CourseDTO co : courses) {
                    System.out.println(co.toString());
                }
            }
        } catch (final InputMismatchException e) {
            System.out.println("You have entered an invalid input. Try again.");
            in.next();               
        }
    }
    
     public static int fillLanguage(final Scanner in) {
         System.out.println("Choose language: 0 - Czech, 1 - Russian, 2 - English");
          try {
              return in.nextInt();              
              
          } catch (final InputMismatchException e) {
            System.out.println("Enter number. You have entered an invalid input.");
            in.next();    // discard non-int input
            return -1;
        }
     
     }
     
     public static int fillDifficulty(final Scanner in) {
         System.out.println("Choose difficulty: 0 - BEGINNER, 1 - ADVANCED ");
          try {
              return in.nextInt();              
              
          } catch (final InputMismatchException e) {
            System.out.println("Enter number. You have entered an invalid input.");
            in.next();    // discard non-int input
            return -1;
        }
     
     }
    
    
    public static void addCourse(ClientCourse clientCourse, final Scanner in) {
        System.out.println("Add course.");
        CourseDTO course = new CourseDTO();
        try {
            System.out.println("Enter course name:");
            String name = in.next();
            course.setName(name);
            int languageNum = fillLanguage(in);
            if((languageNum >= 0) && (languageNum < LanguageSpoken.values().length)){
                 course.setLanguage(LanguageSpoken.values()[languageNum]);
            } else {
                return;
            }
            int diffNum = fillDifficulty(in);
            if((diffNum >= 0) && (diffNum < Difficulty.values().length)){
                 course.setDifficulty(Difficulty.values()[diffNum]);
            } else {
                return;
            }
            if(clientCourse.addCourse(course)){
                System.out.println("Course " + course + " was added succesfully");
            } else {
                 System.out.println("Course " + course + "addition failed");
            }
            
        } catch (final InputMismatchException e) {
            System.out.println("Id should be a number. You have entered an invalid input. Try again.");
            in.next();    // discard non-int input            
        }
    }   
    
    
    public static void modifyCourse(ClientCourse clientCourse, final Scanner in) {
        System.out.println("Modify course.");
        try {
            System.out.println("Enter course id to modify: ");
            int id = in.nextInt();
            CourseDTO course = clientCourse.getCourse(id);
            if (course != null) {
                System.out.println("Enter course new name:");
                String name = in.next();
                course.setName(name);
                int languageNum = fillLanguage(in);
                if ((languageNum >= 0) && (languageNum < LanguageSpoken.values().length)) {
                    course.setLanguage(LanguageSpoken.values()[languageNum]);
                } else {
                    return;
                }
                int diffNum = fillDifficulty(in);
                if ((diffNum >= 0) && (diffNum < Difficulty.values().length)) {
                    course.setDifficulty(Difficulty.values()[diffNum]);
                } else {
                    return;
                }
                if (clientCourse.editCourse(course)) {
                    System.out.println("Course " + course + " was modified succesfully");
                } else {
                    System.out.println("Course " + course + " modification failed");
                }
            }

        } catch (final InputMismatchException e) {
            System.out.println("Id should be a number. You have entered an invalid input. Try again.");
            in.next();    // discard non-int input
        }
    }
    
     public static void deleteCourse(ClientCourse clientCourse, final Scanner in) {
        System.out.println("Delete course.");
        try {
            System.out.println("Enter course id to delete: ");
            int id = in.nextInt();
            
                if (clientCourse.deleteCourse(id)) {
                    System.out.println("Course with id=" + id + " was deleted succesfully");
                } else {
                    System.out.println("Course with id=" + id + " deletion failed");
                }        

        } catch (final InputMismatchException e) {
            System.out.println("Id should be a number. You have entered an invalid input. Try again.");
            in.next();    // discard non-int input

        }
    }
     
      public static void printAllLectures(ClientLecture clientLecture){
       System.out.println("All lectures");
         List<LectureDTO> output =  clientLecture.getAllLectures();        
               for(LectureDTO co:output){
                   System.out.println( co.toString());
               }
    }
   
    public static void printLecture(ClientLecture clientLecture, final Scanner in) {
        System.out.println("Enter lecture id:");
        try {
            int id = in.nextInt();
            LectureDTO lecture = clientLecture.getLecture(id);
            if(lecture != null) {
                System.out.println(lecture);
            }
        } catch (final InputMismatchException e) {
            System.out.println("Id should be a number. You have entered an invalid input. Try again.");
            in.next();    // discard non-int input        
        }
    }
    
     public static void printLecturesByCourse(ClientLecture clientLecture, final Scanner in) {
        System.out.println("List lectures by course.");
        System.out.println("Enter course id:");
        try {
            int id = in.nextInt();
            List<LectureDTO> lectures = clientLecture.getLecturesByCourse(id);
            if (lectures == null || lectures.isEmpty()) {
                System.out.println("No lectures found for course with id= " + id);
            } else {
                for (LectureDTO co : lectures) {
                    System.out.println(co.toString());
                }
            }
        } catch (final InputMismatchException e) {
            System.out.println("Id should be a number. You have entered an invalid input. Try again.");
            in.next();    // discard non-int input        
        }
    }
     
      public static CourseDTO getCourse(ClientCourse clientCourse, final Scanner in) {
        System.out.println("Enter course id:");
        try {
           int id = in.nextInt();
            return clientCourse.getCourse(id);
            
        } catch (final InputMismatchException e) {
            System.out.println("Id should be a number. You have entered an invalid input. Try again.");
            in.next();    // discard non-int input
            return null;
        }
    }
      
     public static Date parseDate(final Scanner in, String dateType) {
        System.out.println("Enter lecture " + dateType + " in format " + FORMAT);
        SimpleDateFormat sdfSource = new SimpleDateFormat(FORMAT);
        String dateString = in.next();    
        try {
            return sdfSource.parse(dateString);
        } catch (ParseException ex) {
           System.out.println("Invalid date format.");
           return null;
        }
    }
     
      public static void addLecture(ClientCourse clientCourse, ClientLecture clientLecture, final Scanner in) {
        System.out.println("Add lecture.");       
        LectureDTO lecture = new LectureDTO();
        try {
            System.out.println("Enter lecture name:");
            String name = in.next();           
            lecture.setName(name);
            System.out.println("Enter lecture roomNumber:");
            String room = in.next();
            lecture.setRoomNumber(room);
            CourseDTO course = getCourse(clientCourse,in);
            if(course == null){
                System.out.println("Invalid course id");
                return;
            }
            lecture.setCourse(course);
            Date startDate = parseDate(in, "Start");
            if(startDate == null) {
                return;
            }
            lecture.setStartTime(startDate);
            Date endDate = parseDate(in, "End");
            if(endDate == null) {
                return;
            }
            lecture.setEndTime(endDate);
            if(clientLecture.addLecture(lecture)){
                System.out.println("Lecture " + lecture + " was added succesfully");
            } else {
                 System.out.println("Lecture " + lecture + "addition failed");
            }
            
        } catch (final InputMismatchException e) {
            System.out.println("Id should be a number. You have entered an invalid input. Try again.");
            in.next();    // discard non-int input            
        }
    }   
      
      public static void modifyLecture(ClientCourse clientCourse, ClientLecture clientLecture, final Scanner in) {
        System.out.println("Modify lecture.");
        try {
            System.out.println("Enter lecture id to modify: ");
            int id = in.nextInt();
            LectureDTO lecture = clientLecture.getLecture(id);
            if (lecture != null) {
                System.out.println("Enter lecture name:");
                String name = in.next();
                lecture.setName(name);
                System.out.println("Enter lecture roomNumber:");
                String room = in.next();
                lecture.setRoomNumber(room);
                CourseDTO course = getCourse(clientCourse, in);
                if (course == null) {
                    System.out.println("Invalid course id");
                    return;
                }
                lecture.setCourse(course);
                Date startDate = parseDate(in, "Start");
                if (startDate == null) {
                    return;
                }
                lecture.setStartTime(startDate);
                Date endDate = parseDate(in, "End");
                if (endDate == null) {
                    return;
                }
                lecture.setEndTime(endDate);
                if (clientLecture.addLecture(lecture)) {
                    System.out.println("Lecture " + lecture + " was added succesfully");
                } else {
                    System.out.println("Lecture " + lecture + "addition failed");
                }
            }

        } catch (final InputMismatchException e) {
            System.out.println("Id should be a number. You have entered an invalid input. Try again.");
            in.next();    // discard non-int input            
        }
    }
      
    public static void deleteLecture(ClientLecture clientLecture, final Scanner in) {
        System.out.println("Delete lecture.");
        try {
            System.out.println("Enter lecture id to delete: ");
            int id = in.nextInt();
            
                if (clientLecture.deleteLecture(id)) {
                    System.out.println("Lecture with id=" + id + " was deleted succesfully");
                } else {
                    System.out.println("Lecture with id=" + id + " deletion failed");
                }        

        } catch (final InputMismatchException e) {
            System.out.println("Id should be a number. You have entered an invalid input. Try again.");
            in.next();    // discard non-int input

        }
    }
    
    
    public static void main( String[] args )
    {
       ClientCourse clientCourse = new  ClientCourse(getURL());
       ClientLecture clientLecture = new  ClientLecture(getURL());
        final Scanner in = new Scanner(System.in);
        int inputInt = -1;
        do {
            try {
                 greeting();
                inputInt = in.nextInt(); // Blocks for user input
                if ((inputInt == 0 ) || ((inputInt > 10) && (inputInt < 17)) || ((inputInt > 20) && (inputInt < 27))) {
                    switch (inputInt){  
                        case 0:
                         printHelp();
                         break;
                        case 11:
                            printAllCourses(clientCourse);
                            break;
                        case 12:
                            printCourse(clientCourse, in);
                            break;
                        case 13:
                            printCourseByName(clientCourse, in);
                            break;
                        case 14:
                            addCourse(clientCourse, in);
                            break;
                        case 15:
                            modifyCourse(clientCourse, in);
                            break;
                        case 16:
                            deleteCourse(clientCourse, in);
                            break;
                        case 21:
                            printAllLectures(clientLecture);
                            break;
                        case 22:
                            printLecture(clientLecture, in);
                            break;
                        case 23:
                            printLecturesByCourse(clientLecture, in);
                            break;
                         case 24:                            
                            addLecture(clientCourse, clientLecture, in);                            
                            break;
                         case 25:                            
                            modifyLecture(clientCourse, clientLecture, in);                            
                            break;
                         case 26:                            
                            deleteLecture(clientLecture, in);                            
                            break;
                         default:
                             System.out.println("Invalid command");
                            break;
                    }                
                   
                } else {
                    if(inputInt != 1){
                        System.out.println("You specified invalid command. Try again.");   
                    }
                }
            } catch (final InputMismatchException e) {
                System.out.println("You have entered an invalid input. Try again.");
                in.next();    // discard non-int input
                continue;     // restart loop, didn't get an integer input
            }
             catch (final ClientHandlerException e) {
                System.out.println("Can't find connection to the server.");              
                break;     // restart loop, didn't get an integer input
            }


        } while (inputInt != 1);

    }
    
}
